<template>
  <div class="custom-tree">
    <!-- 搜索框 -->
    <div v-if="filterable" class="tree-filter">
      <el-input
        v-model="filterText"
        :placeholder="filterPlaceholder"
        :prefix-icon="'el-icon-search'"
        clearable
        @clear="clearFilter"
      />
    </div>
    
    <el-tree
      ref="tree"
      :data="computedTreeData"
      :props="defaultProps"
      :node-key="nodeKey"
      :highlight-current="true"
      :default-expand-all="defaultExpandAll"
      :expand-on-click-node="false"
      :show-checkbox="multiple"
      :check-strictly="checkStrictly"
      :default-checked-keys="defaultCheckedKeys"
      :filter-node-method="filterNode"
      @node-click="handleNodeClick"
      @check="handleCheck"
      @check-change="handleCheckChange"
    >
      <template #default="{ node, data }">
        <div class="custom-tree-node">
          <!-- 图标部分 -->
          <span class="icon-wrapper">
            <i :class="getNodeIcon(data)"></i>
          </span>
          
          <!-- 单选radio部分 -->
          <el-radio
            v-if="!multiple && showRadio"
            v-model="currentRadio"
            :label="data[nodeKey]"
            @change="handleRadioChange(data)"
            @click.native.stop
          >
            {{ node.label }}
          </el-radio>
          
          <!-- 普通节点内容部分 -->
          <span v-else class="node-content">{{ node.label }}</span>
        </div>
      </template>
    </el-tree>
  </div>
</template>

<script>
export default {
  name: 'CustomTree',
  props: {
    // 树形数据
    treeData: {
      type: Array,
      default: null
    },
    // 节点配置选项
    defaultProps: {
      type: Object,
      default: () => ({
        children: 'children',
        label: 'label'
      })
    },
    // 节点的唯一标识
    nodeKey: {
      type: String,
      default: 'id'
    },
    // 是否默认展开所有节点
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 是否显示单选按钮
    showRadio: {
      type: Boolean,
      default: false
    },
    // 是否在严格模式下的多选
    checkStrictly: {
      type: Boolean,
      default: false
    },
    // 默认选中的节点key数组
    defaultCheckedKeys: {
      type: Array,
      default: () => []
    },
    // 默认选中的单选值
    defaultRadioValue: {
      type: [String, Number],
      default: ''
    },
    // 过滤相关配置
    filterable: {
      type: Boolean,
      default: false
    },
    filterPlaceholder: {
      type: String,
      default: '输入关键字进行过滤'
    },
    customFilterNode: {
      type: Function,
      default: null
    }
  },
  
  data() {
    return {
      currentRadio: this.defaultRadioValue,
      filterText: '',
      internalTreeData: []
    }
  },
  
  computed: {
    computedTreeData() {
      return this.treeData || this.internalTreeData;
    }
  },
  
  created() {
    if (!this.treeData) {
      this.getTreeData();
    }
  },
  
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  
  methods: {
    // 获取节点图标
    getNodeIcon(data) {
      return data.children ? 'el-icon-folder' : 'el-icon-document'
    },
    
    // 节点点击事件
    handleNodeClick(data, node) {
      if (!this.multiple && !this.showRadio) {
        this.$emit('node-click', data, node)
      }
    },
    
    // 多选框选择事件
    handleCheck(data, { checkedKeys, checkedNodes, halfCheckedKeys, halfCheckedNodes }) {
      this.$emit('check', {
        checkedKeys,
        checkedNodes,
        halfCheckedKeys,
        halfCheckedNodes
      })
    },
    
    // 多选框状态变化事件
    handleCheckChange(data, checked, indeterminate) {
      this.$emit('check-change', data, checked, indeterminate)
    },
    
    // 单选按钮变化事件
    handleRadioChange(data) {
      this.$emit('radio-change', data)
    },
    
    // 过滤节点方法
    filterNode(value, data) {
      if (this.customFilterNode) {
        return this.customFilterNode(value, data)
      }
      
      if (!value) return true
      
      const label = data[this.defaultProps.label]
      if (!label) return false
      
      return label.toString().toLowerCase()
        .includes(value.toString().toLowerCase())
    },
    
    // 清除过滤
    clearFilter() {
      this.filterText = ''
      this.$refs.tree.filter('')
    },
    
    // 对外暴露的方法
    filter(value) {
      this.filterText = value
    },
    
    getCurrentNode() {
      return this.$refs.tree.getCurrentNode()
    },
    
    setCurrentNode(node) {
      this.$refs.tree.setCurrentNode(node)
    },
    
    getCheckedNodes() {
      return this.$refs.tree.getCheckedNodes()
    },
    
    getCheckedKeys() {
      return this.$refs.tree.getCheckedKeys()
    },
    
    setChecked(key, checked) {
      this.$refs.tree.setChecked(key, checked)
    },
    
    async getTreeData() {
      try {
        const response = await this.fetchTreeData();
        this.internalTreeData = this.formatTreeData(response);
      } catch (error) {
        console.error('获取树形数据失败:', error);
        this.internalTreeData = [];
      }
    },
    
    async fetchTreeData() {
      return [
        {
          id: 1,
          label: '默认节点1',
          children: [
            { id: 2, label: '子节点1-1' },
            { id: 3, label: '子节点1-2' }
          ]
        },
        {
          id: 4,
          label: '默认节点2',
          children: [
            { id: 5, label: '子节点2-1' },
            { id: 6, label: '子节点2-2' }
          ]
        }
      ];
    },
    
    formatTreeData(data) {
      return data.map(item => ({
        id: item.id,
        label: item.label,
        children: item.children ? this.formatTreeData(item.children) : undefined
      }));
    }
  }
}
</script>

<style scoped>
.custom-tree {
  width: 100%;
}

.tree-filter {
  margin-bottom: 10px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  padding-right: 8px;
}

.icon-wrapper {
  margin-right: 8px;
}

.node-content {
  flex: 1;
}

.el-radio {
  margin-right: 0;
  flex: 1;
}

.el-radio__label {
  padding-left: 6px;
}
</style> 